<template>
  <div>
    <div v-if="!file"
      class="upload-area"
      :class="{ 'drag-over': isDragOver }"
      @dragover.prevent="handleDragOver"
      @dragleave.prevent="handleDragLeave"
      @drop.prevent="handleDrop"
    >
      <font-awesome-icon icon="cloud-upload-alt" class="upload-icon" />
      <div class="upload-text">{{ uploadText }}</div>
      <div class="upload-subtext">{{ uploadSubtext }}</div>
      <button class="btn btn-outline" @click="$refs.fileInput.click()">
        <font-awesome-icon icon="folder-open" />
        浏览文件
      </button>
      <input
        type="file"
        class="file-input"
        :accept="acceptedFileTypes"
        @change="handleFileChange"
        ref="fileInput"
      >
    </div>
    <div v-else class="file-preview">
      <font-awesome-icon :icon="fileIcon" class="file-icon" />
      <div class="file-name">{{ file.name }}</div>
      <font-awesome-icon icon="times" class="file-remove" @click="handleRemoveFile" />
    </div>
  </div>
</template>

<script>
export default {
  name: 'FileUploader',
  props: {
    // 允许上传的文件类型
    acceptedFileTypes: {
      type: String,
      default: '.docx,.pdf,.jpg,.jpeg,.png'
    },
    // 上传提示文本
    uploadText: {
      type: String,
      default: '拖拽文件到此处或点击上传'
    },
    // 上传子提示文本
    uploadSubtext: {
      type: String,
      default: '支持Word、PDF和图片文件'
    }
  },
  emits: ['file-selected'],
  data() {
    return {
      // 当前选择的文件
      file: null,
      // 是否处于拖拽文件到上传区域的状态
      isDragOver: false
    };
  },
  computed: {
    // 根据文件类型返回对应的图标
    fileIcon() {
      if (!this.file) return 'file-alt';

      if (this.file.type.includes('image')) {
        return 'file-image';
      } else if (this.file.type.includes('pdf')) {
        return 'file-pdf';
      } else if (
        this.file.type.includes('word') ||
        this.file.name.endsWith('.docx') ||
        this.file.name.endsWith('.doc')
      ) {
        return 'file-word';
      }

      return 'file-alt';
    }
  },
  methods: {
    // 处理文件选择事件
    handleFileChange(e) {
      if (e.target.files && e.target.files.length > 0) {
        this.file = e.target.files[0];
        this.$emit('file-selected', this.file);
      }
    },
    // 处理文件拖拽进入上传区域事件
    handleDragOver() {
      this.isDragOver = true;
    },
    // 处理文件拖拽离开上传区域事件
    handleDragLeave() {
      this.isDragOver = false;
    },
    // 处理文件拖拽到上传区域并放下事件
    handleDrop(e) {
      this.isDragOver = false;

      if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
        this.file = e.dataTransfer.files[0];
        this.$emit('file-selected', this.file);
      }
    },
    // 处理移除已选择文件事件
    handleRemoveFile() {
      this.file = null;
      this.$emit('file-selected', null);
      this.$refs.fileInput.value = '';
    }
  }
};
</script>

<style scoped>
.upload-area {
  border: 2px dashed #d1d5db;
  border-radius: 6px;
  padding: 30px;
  text-align: center;
  margin-bottom: 15px;
  cursor: pointer;
  position: relative;
  transition: all 0.2s;
}

.upload-area:hover {
  border-color: #6366f1;
}

.upload-area.drag-over {
  border-color: #6366f1;
  background-color: rgba(99, 102, 241, 0.05);
}

.upload-icon {
  font-size: 40px;
  color: #9ca3af;
  margin-bottom: 10px;
}

.upload-text {
  color: #6b7280;
  margin-bottom: 5px;
}

.upload-subtext {
  color: #9ca3af;
  font-size: 12px;
  margin-bottom: 15px;
}

.file-input {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
  z-index: -1;
}

.file-preview {
  display: flex;
  align-items: center;
  padding: 10px;
  background-color: #f3f4f6;
  border-radius: 6px;
  margin-bottom: 15px;
}

.file-icon {
  font-size: 20px;
  margin-right: 10px;
  color: #6366f1;
}

.file-name {
  flex: 1;
  font-size: 14px;
  color: #4b5563;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-remove {
  color: #ef4444;
  cursor: pointer;
  font-size: 16px;
  padding: 5px;
}
</style>